#ifndef SUMMIT_H
#define SUMMIT_H

#include <QDataStream>
#include <QString>

class QDataStream;
class QString;

template <typename T>
class Summit {
  template <typename Y>
  friend QDataStream& operator<<(QDataStream& out, const Summit<Y>& summit);
  template <typename Y>
  friend QDataStream& operator>>(QDataStream& in, Summit<Y>& summit);

  public:
    // Pubics Methods
    Summit();
    Summit(const QString& name, const T& info = 1): name(name), info(info) {}
    const QString& getName() const;
    void setName(const QString& name);
    const T& getInfo() const;
    void setInfo(const T&);

    // Publics Attributes
    static int currentNumber;

  private:
    // Privates Attributes
    QString name;
    T info;
};

// Initialisation of current number for namming
template <typename T>
int Summit<T>::currentNumber = 0;

// Default Constructor
template <typename T>
Summit<T>::Summit() {
  name = QString::number(currentNumber++);
  info = 1;
}

// Getter for name attribute
template <typename T>
const QString& Summit<T>::getName() const {
  return name;
}

// Setter for name attribute
template <typename T>
void Summit<T>::setName(const QString& name) {
  this->name = name;
}

// Getter for info attribute
template <typename T>
const T& Summit<T>::getInfo() const {
  return info;
}

// Setter for info attribute
template <typename T>
void Summit<T>::setInfo(const T& info) {
  this->info = info;
}

// Operator << for serialization (writing)
template <typename T>
QDataStream& operator<<(QDataStream& out, const Summit<T>& summit) {
  return out << summit.name << summit.info;
}

// Operator >> for serialization (reading)
template <typename T>
QDataStream& operator>>(QDataStream& in, Summit<T>& summit) {
  return in >> summit.name >> summit.info;
}

#endif
